#include "album_astro.h"
#include "file_utils.h"
#include "elog.h"
#include "elog_file.h"
#include "album_common.h"
#include "timer_utils.h"
#include "img_utils.h"

#include "libhv/json.hpp"

#include <stdlib.h>

#include <string>
#include <filesystem>
#include <fstream>

namespace fs = std::filesystem;
static sqlite3* m_db = nullptr;
static std::string astro_db_filename = "/sdcard/DWARF_II/astro_info.db";
static std::string astro_table_name = "astroInfo";
static std::string astro_folder_path = album_path + astro_path;
static int astro_thumbnail_width = 356;
static int astro_thumbnail_height = 200;


AlbumAstro::AlbumAstro() {

}

AlbumAstro::~AlbumAstro() {

}


int AlbumAstro::createAstroInfoTable(sqlite3* db) {
    char* errMsg = 0;
    int rc;

    m_db = db;
    // 创建astroInfo表（如果还未创建）
    const char* createTableSQL = R"(
        CREATE TABLE IF NOT EXISTS astroInfo (
            id INTEGER PRIMARY KEY,
            file_path TEXT UNIQUE,
            modification_time INTEGER,
            thumbnail_path TEXT,
            file_size INTEGER,
            dec TEXT,
            ra TEXT,
            target TEXT,
            binning TEXT,
            format TEXT,
            exp_time TEXT,
            gain INTEGER,
            shotsToTake INTEGER,
            shotsTaken INTERER,
            shotsStacked INTERER,
            ircut TEXT,
            width TEXT,
            height TEXT,
            media_type INTERER
        );
    )";

    rc = sqlite3_exec(m_db, createTableSQL, NULL, 0, &errMsg);
    if (rc != SQLITE_OK) {
        log_e("cannot create table: %s", errMsg);
        sqlite3_free(errMsg);
    } else {
        log_i("create table successfully");
    }

    return 0;
    
}



int AlbumAstro::insertAstroInfo(const AstroInfo& astro_info) {
    log_i("insertAstroInfo file_path = %s", astro_info.common_info.file_path.c_str());
    if (!m_db) {
        log_e("The database connection is not initialized");
        return -1;
    }

    std::string insertDataSQL = "INSERT INTO " + astro_table_name + " (file_path, modification_time, thumbnail_path, file_size, dec, ra, target, binning, format, exp_time, gain, shotsToTake, shotsTaken, shotsStacked, ircut, width, height, media_type) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);";

    sqlite3_stmt* stmt;
    int rc = sqlite3_prepare_v2(m_db, insertDataSQL.c_str(), -1, &stmt, nullptr);
    if (rc != SQLITE_OK) {
        log_e("can not prepare sql: %s", sqlite3_errmsg(m_db));
        return -1;
    }

    sqlite3_bind_text(stmt, 1, astro_info.common_info.file_path.c_str(), -1, SQLITE_STATIC);
    sqlite3_bind_int64(stmt, 2, astro_info.common_info.modification_time);
    sqlite3_bind_text(stmt, 3, astro_info.common_info.thumbnail_path.c_str(), -1, SQLITE_STATIC);
    sqlite3_bind_int64(stmt, 4, astro_info.common_info.file_size);
    sqlite3_bind_text(stmt, 5, astro_info.unique_info.dec.c_str(), -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 6, astro_info.unique_info.ra.c_str(), -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 7, astro_info.unique_info.target.c_str(), -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 8, astro_info.unique_info.binning.c_str(), -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 9, astro_info.unique_info.format.c_str(), -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 10, astro_info.unique_info.exp_time.c_str(), -1, SQLITE_STATIC);
    sqlite3_bind_int(stmt, 11, astro_info.unique_info.gain);
    sqlite3_bind_int(stmt, 12, astro_info.unique_info.shotsToTake);
    sqlite3_bind_int(stmt, 13, astro_info.unique_info.shotsTaken);
    sqlite3_bind_int(stmt, 14, astro_info.unique_info.shotsStacked);
    sqlite3_bind_text(stmt, 15, astro_info.unique_info.ircut.c_str(), -1, SQLITE_STATIC);
    sqlite3_bind_int(stmt, 16, astro_info.common_info.width);
    sqlite3_bind_int(stmt, 17, astro_info.common_info.height);
    sqlite3_bind_int(stmt, 18, astro_info.common_info.media_type);

    rc = sqlite3_step(stmt);
    if (rc != SQLITE_DONE) {
        log_e("can not insert :%s", sqlite3_errmsg(m_db));
        sqlite3_finalize(stmt);
        return -1;
    }

    sqlite3_finalize(stmt);

    return 0;
}

int AlbumAstro::getCount() {
    int count = 0;

    if (!m_db) {
        log_e("The database connection is not initialized");
        return count;
    }

    std::string sql = "SELECT COUNT(*) FROM " + astro_table_name + ";";
    sqlite3_stmt* stmt;

    int rc = sqlite3_prepare_v2(m_db, sql.c_str(), -1, &stmt, nullptr);
    if (rc != SQLITE_OK) {
        log_e("can not prepare sql: %s", sqlite3_errmsg(m_db));
        return count;
    }

    if (sqlite3_step(stmt) == SQLITE_ROW) {
        count = sqlite3_column_int(stmt, 0);
    }

    sqlite3_finalize(stmt);

    return count;
}

std::vector<AstroInfo> AlbumAstro::queryAstroInfoByTime() {
    std::vector<AstroInfo> result;

    if (!m_db) {
        log_e("The database connection is not initialized");
        return result;
    }

    std::string sql = "SELECT * FROM " + astro_table_name + " ORDER BY modification_time DESC;";
    sqlite3_stmt* stmt;

    int rc = sqlite3_prepare_v2(m_db, sql.c_str(), -1, &stmt, nullptr);
    if (rc != SQLITE_OK) {
        log_e("can not prepare sql: %s", sqlite3_errmsg(m_db));
        return result;
    }

    while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
        AstroInfo info;
        info.common_info.file_path = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1));
        info.common_info.modification_time = sqlite3_column_int64(stmt, 2);
        info.common_info.thumbnail_path = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 3));
        info.common_info.file_size = sqlite3_column_int64(stmt, 4);
        info.unique_info.dec = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 5));
        info.unique_info.ra = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 6));
        info.unique_info.target = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 7));
        info.unique_info.binning = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 8));
        info.unique_info.format = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 9));
        info.unique_info.exp_time = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 10));
        info.unique_info.gain = sqlite3_column_int(stmt, 11);
        info.unique_info.shotsToTake = sqlite3_column_int(stmt, 12);
        info.unique_info.shotsTaken = sqlite3_column_int(stmt, 13);
        info.unique_info.shotsStacked = sqlite3_column_int(stmt, 14);
        info.unique_info.ircut = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 15));
        info.common_info.width = sqlite3_column_int(stmt, 16);
        info.common_info.height = sqlite3_column_int(stmt, 17);
        info.common_info.media_type = sqlite3_column_int(stmt, 18);
        result.push_back(info);
    }

    sqlite3_finalize(stmt);

    return result;
}
    
std::vector<AstroInfo> AlbumAstro::queryAllAstroInfo() {
    std::vector<AstroInfo> result;

    if (!m_db) {
        log_e("The database connection is not initialized");
        return result;
    }

    std::string sql = "SELECT * FROM " + astro_table_name + ";";
    sqlite3_stmt* stmt;

    int rc = sqlite3_prepare_v2(m_db, sql.c_str(), -1, &stmt, nullptr);
    if (rc != SQLITE_OK) {
        log_e("can not prepare sql: %s", sqlite3_errmsg(m_db));
        return result;
    }

    while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
        AstroInfo info;
        info.common_info.file_path = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1));
        info.common_info.modification_time = sqlite3_column_int64(stmt, 2);
        info.common_info.thumbnail_path = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 3));
        info.common_info.file_size = sqlite3_column_int64(stmt, 4);
        info.unique_info.dec = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 5));
        info.unique_info.ra = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 6));
        info.unique_info.target = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 7));
        info.unique_info.binning = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 8));
        info.unique_info.format = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 9));
        info.unique_info.exp_time = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 10));
        info.unique_info.gain = sqlite3_column_int(stmt, 11);
        info.unique_info.shotsToTake = sqlite3_column_int(stmt, 12);
        info.unique_info.shotsTaken = sqlite3_column_int(stmt, 13);
        info.unique_info.shotsStacked = sqlite3_column_int(stmt, 14);
        info.unique_info.ircut = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 15));
        info.common_info.width = sqlite3_column_int(stmt, 16);
        info.common_info.height = sqlite3_column_int(stmt, 17);
        info.common_info.media_type = sqlite3_column_int(stmt, 18);
        result.push_back(info);
    }

    sqlite3_finalize(stmt);

    return result;
}

std::vector<AstroInfo> AlbumAstro::queryAstroInfoByFilepath(const std::string& file_path) {
    std::vector<AstroInfo> result;

    if (!m_db) {
        log_e("The database connection is not initialized");
        return result;
    }

    std::string sql = "SELECT * FROM " + astro_table_name + " WHERE file_path = ?";
    sqlite3_stmt* stmt;

    int rc = sqlite3_prepare_v2(m_db, sql.c_str(), -1, &stmt, nullptr);
    if (rc != SQLITE_OK) {
        log_e("can not prepare sql: %s", sqlite3_errmsg(m_db));
        return result;
    }

    sqlite3_bind_text(stmt, 1, file_path.c_str(), -1, SQLITE_STATIC);

    while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
        AstroInfo info;
        info.common_info.file_path = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1));
        info.common_info.modification_time = sqlite3_column_int64(stmt, 2);
        info.common_info.thumbnail_path = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 3));
        info.common_info.file_size = sqlite3_column_int64(stmt, 4);
        info.unique_info.dec = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 5));
        info.unique_info.ra = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 6));
        info.unique_info.target = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 7));
        info.unique_info.binning = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 8));
        info.unique_info.format = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 9));
        info.unique_info.exp_time = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 10));
        info.unique_info.gain = sqlite3_column_int(stmt, 11);
        info.unique_info.shotsToTake = sqlite3_column_int(stmt, 12);
        info.unique_info.shotsTaken = sqlite3_column_int(stmt, 13);
        info.unique_info.shotsStacked = sqlite3_column_int(stmt, 14);
        info.unique_info.ircut = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 15));
        info.common_info.width = sqlite3_column_int(stmt, 16);
        info.common_info.height = sqlite3_column_int(stmt, 17);
        info.common_info.media_type = sqlite3_column_int(stmt, 18);
        result.push_back(info);
    }

    sqlite3_finalize(stmt);

    return result;
}

std::vector<AstroInfo> AlbumAstro::queryAstroInfoByTime(int page_index, int page_size) {
    std::vector<AstroInfo> result;

    if (!m_db) {
        log_e("The database connection is not initialized");
        return result;
    }

    std::string sql = "SELECT * FROM " + astro_table_name + " ORDER BY modification_time DESC LIMIT ? OFFSET ?;";
    sqlite3_stmt* stmt;

    int rc = sqlite3_prepare_v2(m_db, sql.c_str(), -1, &stmt, nullptr);
    if (rc != SQLITE_OK) {
        log_e("can not prepare sql: %s", sqlite3_errmsg(m_db));
        return result;
    }

    int offset = page_index * page_size;
    sqlite3_bind_int(stmt, 1, page_size);
    sqlite3_bind_int(stmt, 2, offset);

    while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
        AstroInfo info;
        info.common_info.file_path = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1));
        info.common_info.modification_time = sqlite3_column_int64(stmt, 2);
        info.common_info.thumbnail_path = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 3));
        info.common_info.file_size = sqlite3_column_int64(stmt, 4);
        info.unique_info.dec = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 5));
        info.unique_info.ra = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 6));
        info.unique_info.target = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 7));
        info.unique_info.binning = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 8));
        info.unique_info.format = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 9));
        info.unique_info.exp_time = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 10));
        info.unique_info.gain = sqlite3_column_int(stmt, 11);
        info.unique_info.shotsToTake = sqlite3_column_int(stmt, 12);
        info.unique_info.shotsTaken = sqlite3_column_int(stmt, 13);
        info.unique_info.shotsStacked = sqlite3_column_int(stmt, 14);
        info.unique_info.ircut = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 15));
        info.common_info.width = sqlite3_column_int(stmt, 16);
        info.common_info.height = sqlite3_column_int(stmt, 17);
        info.common_info.media_type = sqlite3_column_int(stmt, 18);
        result.push_back(info);
    }

    sqlite3_finalize(stmt);

    return result;
}

bool AlbumAstro::updateAstroInfo(const std::string& file_path, const std::string& new_filename) {
    if (!m_db) {
        log_e("The database connection is not initialized");
        return false;
    }

    std::string sql = "UPDATE " + astro_table_name + " SET file_path = ? WHERE file_path = ?;";
    sqlite3_stmt* stmt;

    int rc = sqlite3_prepare_v2(m_db, sql.c_str(), -1, &stmt, nullptr);
    if (rc != SQLITE_OK) {
        log_e("can not prepare sql: %s", sqlite3_errmsg(m_db));
        return false;
    }

    sqlite3_bind_text(stmt, 1, new_filename.c_str(), -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 2, file_path.c_str(), -1, SQLITE_STATIC);

    rc = sqlite3_step(stmt);
    if (rc != SQLITE_DONE) {
        log_e("can not update: %s", sqlite3_errmsg(m_db));
        sqlite3_finalize(stmt);
        return false;
    }

    sqlite3_finalize(stmt);

    return true;
}
    
bool AlbumAstro::deleteAstroInfo(const std::string& file_path) {
    log_i("deleteAstroInfo file_path = %s", file_path.c_str());

    if (!m_db) {
        log_e("The database connection is not initialized");
        return false;
    }

    std::string sql = "DELETE FROM " + astro_table_name + " WHERE file_path = ?;";
    sqlite3_stmt* stmt;

    int rc = sqlite3_prepare_v2(m_db, sql.c_str(), -1, &stmt, nullptr);
    if (rc != SQLITE_OK) {
        log_e("can not prepare sql: %s", sqlite3_errmsg(m_db));
        return false;
    }

    sqlite3_bind_text(stmt, 1, file_path.c_str(), -1, SQLITE_STATIC);

    rc = sqlite3_step(stmt);
    if (rc != SQLITE_DONE) {
        log_e("can not delete: %s", sqlite3_errmsg(m_db));
        sqlite3_finalize(stmt);
        return false;
    }

    sqlite3_finalize(stmt);
    
    return true;
}
    
void AlbumAstro::printAstroInfo(const AstroInfo& astro_info) {
    log_i("astro_info file_path = %s", astro_info.common_info.file_path.c_str());
    log_i("astro_info modification_time = %ld", astro_info.common_info.modification_time);
    log_i("astro_info thumbnail_path = %s", astro_info.common_info.thumbnail_path.c_str());
    log_i("astro_info file_size = %d", astro_info.common_info.file_size);
    log_i("astro_info dec = %s", astro_info.unique_info.dec.c_str());
    log_i("astro_info ra = %s", astro_info.unique_info.ra.c_str());
    log_i("astro_info target = %s", astro_info.unique_info.target.c_str());
    log_i("astro_info binning = %s", astro_info.unique_info.binning.c_str());
    log_i("astro_info format = %s", astro_info.unique_info.format.c_str());
    log_i("astro_info exp_time = %s", astro_info.unique_info.exp_time.c_str());
    log_i("astro_info gain = %d", astro_info.unique_info.gain);
    log_i("astro_info shotsToTake = %d", astro_info.unique_info.shotsToTake);
    log_i("astro_info shotsTaken = %d", astro_info.unique_info.shotsTaken);
    log_i("astro_info shotsStacked = %d", astro_info.unique_info.shotsStacked);
    log_i("astro_info ircut = %s", astro_info.unique_info.ircut.c_str());
}


/// @brief 删除天文图片整个文件夹
/// @param file_path 天文叠图文件的路径
/// @return 
bool AlbumAstro::deleteDirectory(const std::string& file_path) {
    std::string astro_dir = extractFolderPath(file_path, 1);

    if (astro_dir != "" && isPathContains(astro_dir, astro_folder_path) && astro_dir.size() > astro_folder_path.size()) {
        if (deleteAstroInfo(file_path)) {
            deleteFolder(astro_dir);
            return true;
        } else {
            return false;
        }
    }

    return false;
}


/// @brief 重命名天文图片文件夹名称
/// @param file_path 天文叠图文件的路径
/// @param new_astro_name 新的文件夹名称
/// @return 
bool AlbumAstro::renameDirectory(const std::string& file_path, const std::string& new_astro_name) {
    std::string astro_dir = extractFolderPath(file_path, 1);

    if (astro_dir != "" && isPathContains(astro_dir, astro_folder_path) && astro_dir.size() > astro_folder_path.size()) {
        std::string new_astro_path = astro_folder_path + new_astro_name;
        if (renameFile(astro_dir, new_astro_path)) {
            updateAstroInfo(astro_dir, new_astro_path);
            return true;
        } else {
            return false;
        }
    }

    return false;
}


/// @brief 天文叠图完成后，更新天文图片数据库
/// @param folder_path 天文叠图文件夹路径
/// @return 
int AlbumAstro::updateAstro(const std::string& folder_path) {
    log_i("updateAstro folder_path = %s", folder_path.c_str());
    std::string output_image_path = folder_path + "/stacked_thumbnail.jpg";
    std::string output_png_image_path = folder_path + "/stacked_thumbnail.png";
    std::string input_image_path = folder_path + "/stacked.png";
    std::string input_jpg_image_path = folder_path + "/stacked.jpg";
    std::string shots_info_path = folder_path + "/shotsInfo.json";

    if (fs::exists(input_jpg_image_path) && getImageSize(output_image_path).width != album_thumbnail_width) {
        imageDownsample(input_jpg_image_path, output_image_path, album_thumbnail_width, album_thumbnail_height);
    }

    if (fs::exists(input_image_path) && getImageSize(output_png_image_path).width != album_thumbnail_width) {
        imageDownsample(input_image_path, output_png_image_path, album_thumbnail_width, album_thumbnail_height);
    }

    std::vector<AstroInfo> astro_info_list_jpg = queryAstroInfoByFilepath(input_jpg_image_path);
    std::vector<AstroInfo> astro_info_list_png = queryAstroInfoByFilepath(input_image_path);
    if (!astro_info_list_jpg.empty() || !astro_info_list_png.empty())
        return 0;

    if (folder_path != "" && isPathContains(folder_path, astro_folder_path) && folder_path.size() > astro_folder_path.size()) {
        // 如果文件夹里面有名称为stacked.png的文件，则将stacked.png降采样为指定大小，保存为stacked_thumbnail.png
        if (fs::exists(input_image_path) || fs::exists(input_jpg_image_path)) {
            AstroInfo astro_info;
            time_checker time_test;
            time_test.start();

            if (fs::exists(input_image_path)) {
                astro_info.common_info.thumbnail_path = output_png_image_path;
            }
                

            if (fs::exists(input_jpg_image_path)) {
                astro_info.common_info.thumbnail_path = output_image_path;
            }
                
            
            time_test.stop();
            time_test.show_distance("image downsample cost time ");

            // 读取天文图片信息
            std::ifstream shots_info_file(shots_info_path);
            if (!shots_info_file.is_open()) {
                log_e("can not open file");
                return -1;
            }

            nlohmann::json root;
            try {
                shots_info_file >> root;
            } catch (const std::exception& e) {
                // 捕获并处理异常
                log_i("An exception occurred: %s", e.what());
            }

            shots_info_file.close();

            if (fs::exists(input_image_path)) {
                astro_info.common_info.file_path = input_image_path;
                astro_info.common_info.modification_time = getFileModifiedTime(input_image_path);
                astro_info.common_info.file_size = getFileSizeInt(input_image_path);
            } else if (fs::exists(input_jpg_image_path)) {
                astro_info.common_info.file_path = input_jpg_image_path;
                astro_info.common_info.modification_time = getFileModifiedTime(input_jpg_image_path);
                astro_info.common_info.file_size = getFileSizeInt(input_jpg_image_path);
            }
            

            astro_info.common_info.width = 0;
            astro_info.common_info.height = 0;
            astro_info.common_info.media_type = MEDIA_ASTRO;

            if (!root.empty()) {
                try {
                    if (root["DEC"].is_string()) {
                        std::string decString = root["DEC"];
                        astro_info.unique_info.dec = decString;
                    } else if (root["DEC"].is_number()) {
                        double dec = root["DEC"];
                        astro_info.unique_info.dec = std::to_string(dec);
                    }

                    if (root["RA"].is_string()) {
                        std::string raString = root["RA"];
                        astro_info.unique_info.ra = raString;
                    } else if (root["RA"].is_number()) {
                        double ra = root["RA"];
                        astro_info.unique_info.ra = std::to_string(ra);
                    }

                    astro_info.unique_info.target = root.value("target", "");

                    if (root["binning"].is_number()) {
                        int binning = root["binning"];
                        astro_info.unique_info.binning = std::to_string(binning);
                    } else if (root["binning"].is_string()) {
                        std::string binning_str = root["binning"];
                        astro_info.unique_info.binning = binning_str;
                    }
                    astro_info.unique_info.format = root.value("format", "");
                    
                    if (root["exp"].is_number()) {
                        double expValue = root["exp"];
                        astro_info.unique_info.exp_time = std::to_string(expValue);
                    } else if (root["exp"].is_string()) {
                        std::string expString = root["exp"];
                        astro_info.unique_info.exp_time = expString;
                    }

                    if (root.contains("ir")) {
                        astro_info.unique_info.ircut = root["ir"];
                    } else {
                        astro_info.unique_info.ircut = "";
                    }

                    astro_info.unique_info.gain = root.value("gain", 0); // 默认为0
                    astro_info.unique_info.shotsToTake = root.value("shotsToTake", 0); // 默认为0
                    astro_info.unique_info.shotsTaken = root.value("shotsTaken", 0); // 默认为0
                    astro_info.unique_info.shotsStacked = root.value("shotsStacked", 0); // 默认为0
                } catch(const std::exception& e) {
                    log_i("parse json error");
                }
                
            }

            printAstroInfo(astro_info);
            insertAstroInfo(astro_info);

            fileSync();

            return 0;
        }

        return -1;
    }

    return -1;
}